package fr.utbm.to52.android_bibtex.main;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import fr.utbm.to52.android_bibtex.R;
import fr.utbm.to52.android_bibtex.controller.FieldController;
import fr.utbm.to52.android_bibtex.model.entry.Entry;
import fr.utbm.to52.android_bibtex.model.entry.Field;
import fr.utbm.to52.android_bibtex.model.spec.EntryDefinition.FieldSpecificationCategory;
import fr.utbm.to52.android_bibtex.model.spec.FieldSpecification;
import fr.utbm.to52.android_bibtex.model.spec.FieldSpecifications;
import fr.utbm.to52.android_bibtex.model.spec.Month;
import fr.utbm.to52.android_bibtex.model.spec.ValueType;

public class FieldActivity extends Activity {

	private TextView entryType;
	private EditText editKey;
	private boolean createMode;
	private final Collection<Field> fields = new ArrayList<Field>();
	private FieldController controller;
	private Spinner monthSpinner;
	private boolean monthSpinnerInited;

	public static Entry entry;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.field);
		this.controller = new FieldController(this);
		this.entryType = (TextView) findViewById(R.id.textViewEntryType);
		this.editKey = (EditText) findViewById(R.id.editTextKey);
		this.monthSpinner = new Spinner(this);

		this.createMode = getIntent().getBooleanExtra("createMode", true);

		setView();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.field_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		return this.controller.itemSelectedAction(item);
	}

	@Override
	public boolean onPrepareOptionsMenu (Menu menu) {
		if (!this.createMode) {
			menu.getItem(0).setEnabled(false);
			menu.getItem(0).setVisible(false);
		} else {
			menu.getItem(1).setEnabled(false);
			menu.getItem(1).setVisible(false);
		}
		return true;
	}

	public TextView getEntryType() {
		return this.entryType;
	}

	public EditText getEditKey() {
		return this.editKey;
	}

	public Collection<Field> getFields() {
		return this.fields;
	}

	public FieldController getController() {
		return this.controller;
	}

	public Spinner getMonthSpinner() {
		return this.monthSpinner;
	}

	public void setMonthSpinner(Spinner monthSpinner) {
		this.monthSpinner = monthSpinner;
	}

	public void setView() {
		this.entryType.setText(entry.getDefinition().getName());
		this.editKey.setText(entry.getKey());
		this.editKey.addTextChangedListener(new TextWatcher() {
			@Override
			public void onTextChanged(CharSequence s, int start, int before, int count) { }
			@Override
			public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

			@Override
			public void afterTextChanged(Editable s) {
				entry.setKey(s.toString());
				MainActivity.entryListChanged = true;
			}
		});

		Month[] monthArray = Month.values;
		ArrayAdapter<Month> adapter = new ArrayAdapter<Month>(this, android.R.layout.simple_spinner_dropdown_item, monthArray);
		this.monthSpinner.setAdapter(adapter);

		LinearLayout layoutRq = (LinearLayout) findViewById(R.id.linearLayoutRq);
		LinearLayout layoutRc = (LinearLayout) findViewById(R.id.linearLayoutRc);
		LinearLayout layoutOp = (LinearLayout) findViewById(R.id.linearLayoutOp);
		addFields(layoutRq, FieldSpecificationCategory.REQUIRED);
		addFields(layoutRc, FieldSpecificationCategory.RECOMMENDED);
		addOptionalFields(layoutOp);

	}

	private void addOptionalFields(LinearLayout layout) {
		for (FieldSpecification fs : FieldSpecifications.getInstance().getSpecifications().values()) {
			if (entry.getDefinition().getCategoryOf(fs) == null) {
				addEditText(layout, fs);
			}
		}
	}

	public void addFields(LinearLayout layout, FieldSpecificationCategory fsCategory) {
		Set<FieldSpecification> specificationFields =  entry.getDefinition().getFieldSpecificationsOfCategory(fsCategory);
		for (FieldSpecification fs : specificationFields) {
			addEditText(layout, fs);
		}
	}

	public void addEditText(LinearLayout layout, FieldSpecification fs) {
		TextView txt = new TextView(this);
		txt.setText(fs.getName());
		EditText edit = new EditText(this);

		final Field field;
		if (this.createMode) {
			field = new Field(fs);
			this.fields.add(field);
		} else {
			if (entry.getFields().containsKey(fs)) {
				field = entry.getFields().get(fs);
			} else {
				field = new Field(fs);
				entry.addField(field);
			}
			if (field.getValue() != null) {
				if (fs.getType() == ValueType.MONTH) {
					this.monthSpinner.setSelection(((Month) field.getValue()).ordinal());
				} else {
					edit.setText(field.stringValue());
				}
			}
		}

		switch (field.getSpecification().getType()) {
		case NUMBER:
		case NUMBER_RANGE:
			edit.setInputType(InputType.TYPE_CLASS_NUMBER);
			break;
		case URI:
			edit.setInputType(InputType.TYPE_TEXT_VARIATION_URI);
			break;
		case MONTH:
			break;
		default:
			edit.setInputType(InputType.TYPE_CLASS_TEXT);
		}

		if ("abstract".equals(fs.getName())) {
			// multiline but disallowing line returns
			edit.setHorizontallyScrolling(false);
			edit.setInputType(edit.getInputType() | InputType.TYPE_TEXT_FLAG_MULTI_LINE | InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT);
		}

		if (field.getSpecification().getType() == ValueType.MONTH) {
			this.monthSpinnerInited = false;
			this.monthSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
				@Override
				public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
					if (FieldActivity.this.monthSpinnerInited) {
						Object o = FieldActivity.this.monthSpinner.getItemAtPosition(position);
						Month m = (Month) o;
						field.setValue(m);
						MainActivity.entryListChanged = true;
					} else {  // First call by Android
						FieldActivity.this.monthSpinnerInited = true;
					}
				}
				@Override
				public void onNothingSelected(AdapterView<?> parentView) { }
			});
		} else {
			edit.addTextChangedListener(new TextWatcher() {
				@Override
				public void onTextChanged(CharSequence s, int start, int before, int count) { }
				@Override
				public void beforeTextChanged(CharSequence s, int start, int count, int after) { }

				@Override
				public void afterTextChanged(Editable s) {
					field.setValue(s.toString());
					MainActivity.entryListChanged = true;
				}
			});
		}

		layout.addView(txt);
		if (fs.getType() == ValueType.MONTH) {
			layout.addView(this.monthSpinner);
		} else {
			layout.addView(edit);
		}
	}

}
